package org.erepublik.company.controllers;

import java.util.ArrayList;
import java.util.Arrays;

import org.erepublik.company.CompanyForSale;
import org.erepublik.company.ECountry;
import org.erepublik.company.EProductType;
import org.erepublik.company.searchCriteria.CompanySearchCriteria;
import org.erepublik.company.searchCriteria.ECompanyQuality;
import org.erepublik.company.searchCriteria.ELicensesNumber;
import org.erepublik.company.searchCriteria.EMinimumStock;
import org.erepublik.company.service.IProductsService;
import org.erepublik.company.service.JSONCompanyForSaleService;
import org.erepublik.company.service.JSONCountryDataProvider;
import org.erepublik.company.service.XmlVatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/companiesForSale.html")
public class CompaniesForSaleController extends AbstractController {

    @Autowired
    JSONCompanyForSaleService companyService;
    
    @Autowired
    private IProductsService productService; 

    @Autowired
    private XmlVatService vatService; 
    
    @Autowired
    private JSONCountryDataProvider dataService;
    
    @RequestMapping(method = RequestMethod.GET)
    public String showForm(ModelMap model) {
        fillModelMap(model);
        CompanyForSale[] companies = companyService.getCompanies(null);
        
        Arrays.sort(companies);
        companies = shrinkTable(companies);
        setServices(companies);
        
        model.addAttribute("updateTime", companyService.getMinutesSinceUpdate() );
        model.addAttribute("companies", companies);
        model.addAttribute("companySearchCriteria", new CompanySearchCriteria());

        return "companiesForSale";
    }

    private void setServices(CompanyForSale[] companies) {
        for (CompanyForSale companyForSale : companies) {
            companyForSale.setServices(productService, vatService, dataService);
        }
        
    }

    @RequestMapping(method = RequestMethod.POST)
    public String showList(ModelMap model, @ModelAttribute("companySearchCriteria") CompanySearchCriteria criteria) {
        fillModelMap(model);
        CompanyForSale[] products = companyService.getCompanies(null);
        
        Arrays.sort(products);
        products = filter(products, criteria.getCompanyQuality(), criteria.getProductType(), 
                criteria.getMinimumStock(), criteria.getCountry(), criteria.getLicencesNumber() );
        products = shrinkTable(products);
        setServices(products);

        
        model.addAttribute("updateTime", companyService.getMinutesSinceUpdate() );
        model.addAttribute("companies", products);
        model.addAttribute("companySearchCriteria", criteria);

        return "companiesForSale";
    }
    
    
    private CompanyForSale[] filter(CompanyForSale[] products, ECompanyQuality companyQuality, EProductType productType, 
                EMinimumStock eMinimumStock, ECountry eCountry, ELicensesNumber eLicensesNumber) {
        ArrayList<CompanyForSale> companies = new ArrayList<CompanyForSale>();
        for (CompanyForSale companyForSale : products) {
            if ( companyQuality!=ECompanyQuality.ALL && companyQuality.getValue() != companyForSale.getQuality())
                continue;
            if (productType!= null && productType != companyForSale.getProductType())
                continue;
            if (eMinimumStock.getValue() > companyForSale.getStockSize())
                continue;
            if (eCountry!=null && companyForSale.getCountry() != eCountry)
                continue;
            if (eLicensesNumber.getValue() > companyForSale.getLicenses().length)
                continue;
            
            companies.add(companyForSale);
        }
        
        return companies.toArray(new CompanyForSale[0]);
    }


    final int MAX_SIZE=100; // maksymalna ilosc wyswietlanych produktow
    // skraca tabele do MAX_SIZE produktow
    private CompanyForSale[] shrinkTable(CompanyForSale[] products) {
        if (products.length <= MAX_SIZE)
            return products;
        else {
            CompanyForSale[] newTable = new CompanyForSale[MAX_SIZE];
            for (int i=0; i < MAX_SIZE; i++) {
                newTable[i]=products[i];
            }
            return newTable;
        }
    }
    
    
}
